import { getUUID } from '@/utils/common.js'
import WKT from 'terraformer-wkt-parser';

export function coordinatesArrayToCartesianArray(coordinates, crsFunction) {
  let positions = new Array(coordinates.length);
  for (var i = 0; i < coordinates.length; i++) {
    positions[i] = Cesium.Cartesian3.fromDegrees(coordinates[i][0], coordinates[i][1], coordinates[i][2])
  }
  return positions;
}

export function createPolygon(geoJson, coordinates, options) {
  if (coordinates.length === 0 || coordinates[0].length === 0) {
    return;
  }

  let widthProperty = null
  let outlineColorProperty = null
  let materialProperty = null

  var properties = geoJson.properties;
  if (Cesium.defined(properties)) {
    var width = properties["stroke-width"];
    if (Cesium.defined(width)) {
      widthProperty = new Cesium.ConstantProperty(width);
    }

    var color;
    var stroke = properties.stroke;
    if (Cesium.defined(stroke)) {
      color = Cesium.Color.fromCssColorString(stroke);
    }
    var opacity = properties["stroke-opacity"];
    if (Cesium.defined(opacity) && Cesium.defined(stroke)) {
      color.alpha = opacity;
    }

    if (Cesium.defined(color)) {
      outlineColorProperty = new Cesium.ConstantProperty(color);
    }

    let fillColor;
    const fill = properties.fill;
    const fillOpacity = properties["fill-opacity"];
    if (Cesium.defined(fill)) {
      fillColor = Cesium.Color.fromCssColorString(fill);
      if (Cesium.defined(fillOpacity)) {
        fillColor.alpha = fillOpacity
      }
    }

    if (Cesium.defined(fillColor)) {
      materialProperty = new Cesium.ColorMaterialProperty(fillColor);
    }
  }

  let polygon = new Cesium.PolygonGraphics();
  polygon.outline = new Cesium.ConstantProperty(true);
  polygon.fill = options.fill

  polygon.outlineColor = options.outlineColor || outlineColorProperty
  polygon.outlineWidth = options.outlineWidth || widthProperty;
  polygon.material = options.material || materialProperty;
  const arcType = options.arcType || Cesium.ArcType.RHUMB;
  polygon.arcType = new Cesium.ConstantProperty(arcType);

  let holes = [];
  for (let i = 1, len = coordinates.length; i < len; i++) {
    holes.push(
      new Cesium.PolygonHierarchy(
        coordinatesArrayToCartesianArray(coordinates[i])
      )
    );
  }

  let positions = coordinates[0];
  polygon.hierarchy = new Cesium.ConstantProperty(
    new Cesium.PolygonHierarchy(
      coordinatesArrayToCartesianArray(positions),
      holes
    )
  );
  if (positions[0].length > 2) {
    polygon.perPositionHeight = new Cesium.ConstantProperty(true);
  } else {
    polygon.heightReference = options.clampToGround || Cesium.HeightReference.CLAMP_TO_GROUND;
  }

  if (options.extrudedHeight) {
    let startHeight = 0
    const targetHeight = options.extrudedHeight
    const speed = options.speed || 10
    polygon.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
    //polygon.extrudedHeightReference = Cesium.HeightReference.CLAMP_TO_GROUND;
    polygon.extrudedHeight = new Cesium.CallbackProperty(() => {
      startHeight += speed;
      if (startHeight > targetHeight) {
        startHeight = targetHeight;
      }
      return startHeight;
    }, false)
  }

  return polygon
}

export function createPolyline(geoJson, coordinates, options) {
  var material = null
  var widthProperty = null

  var properties = geoJson.properties;
  if (Cesium.defined(properties)) {
    var width = properties["stroke-width"];
    if (Cesium.defined(width)) {
      widthProperty = new Cesium.ConstantProperty(width);
    }

    var color;
    var stroke = properties.stroke;
    if (Cesium.defined(stroke)) {
      color = Cesium.Color.fromCssColorString(stroke);
    }
    var opacity = properties["stroke-opacity"];
    if (Cesium.defined(opacity) && opacity !== 1.0) {
      if (Cesium.defined(color)) {
        color.alpha = opacity;
        material = new Cesium.ColorMaterialProperty(color);
      }
    }

  }

  var polylineGraphics = new Cesium.PolylineGraphics();
  polylineGraphics.clampToGround = options.clampToGround || Cesium.HeightReference.CLAMP_TO_GROUND;
  polylineGraphics.material = options.color || material;
  polylineGraphics.width = options.width || widthProperty;
  polylineGraphics.positions = new Cesium.ConstantProperty(
    coordinatesArrayToCartesianArray(coordinates)
  );
  const arcType = options.arcType || Cesium.ArcType.RHUMB;
  polylineGraphics.arcType = new Cesium.ConstantProperty(arcType);

  return polylineGraphics
}

export function clearFeatureByName(name) {
  const entityArr = global.viewer.entities.values
  const removeEntities = []
  for (let i = 0; i < entityArr.length; i++) {
    const entity = entityArr[i]
    if (entity.cname == name || entity.name == name) {
      removeEntities.push(entity)
    }
  }
  removeEntities.forEach(entity => {
    global.viewer.entities.remove(entity)
  })
}


export function findFeatureByName(name) {
  const entityArr = global.viewer.entities.values
  return entityArr.find(f => f.cname === name || f.name === name)
}

export function clearFeatureByNameLike(name) {
  const entityArr = global.viewer.entities.values
  return entityArr.filter(f => f.name && f.name.indexOf(name) > -1).forEach(e => {
    global.viewer.entities.remove(e)
  })
}

export function findFeatureByNameLike(name) {
  const entityArr = global.viewer.entities.values
  return entityArr.filter(f => f.cname.indexOf(name) + f.name.indexOf(name) > -2)
}

export function drawPolyline(name, geoJson, coordinates, options) {
  const entities = global.viewer.entities
  const polylineGraphics = createPolyline(geoJson, coordinates, options)
  if (polylineGraphics) {
    const guid = getUUID()
    const entity = {
      id: guid,
      name: name,
      cname: name
    }
    if (Cesium.defined(geoJson.properties)) {
      entity.properties = properties;
    }
    entity.cname = name
    entity.polyline = polylineGraphics
    entities.add(entity)
  }
}

export function drawMultiPolyline(name, geoJson, polylines, options) {
  for (var i = 0; i < polylines.length; i++) {
    drawPolyline(name, geoJson, polylines[i], options)
  }
}

export function drawPolygonNoFill(name, geoJson, coordinates, options) {
  drawMultiPolyline(name, geoJson, coordinates, options)
}

export function drawPolygonWithFill(name, geoJson, coordinates, options) {
  const entities = global.viewer.entities
  const polygonGraphics = createPolygon(geoJson, coordinates, options)
  if (polygonGraphics) {
    const guid = getUUID()
    const entity = {
      id: guid,
      name: name,
      cname: name
    }
    if (Cesium.defined(geoJson.properties)) {
      entity.properties = properties;
    }
    entity.cname = name
    entity.polygon = polygonGraphics
    entities.add(entity)
  }
}

export function drawPolygon(name, geoJson, coordinates, options) {
  if (options.fill) {
    drawPolygonWithFill(name, geoJson, coordinates, options)
    if (options.outline && !options.extrudedHeight) {
      drawPolygonNoFill(name, geoJson, coordinates, options)
    }
  } else {
    if (options.outlineColor) {
      options.color = options.outlineColor
    }
    if (options.outlineWidth) {
      options.width = options.outlineWidth
    }
    drawPolygonNoFill(name, geoJson, coordinates, options)
  }
}

export function drawMulitPolygon(name, geoJson, polygons, options) {
  for (var i = 0; i < polygons.length; i++) {
    drawPolygon(name, geoJson, polygons[i], options)
  }
}

export function drawFeatureFromWKT(name, wkt, options) {
  const geojson = WKT.parse(wkt)
  const geoType = geojson.type
  switch (geoType) {
    case 'LineString':
      drawPolyline(name, geojson, geojson.coordinates, options)
      break
    case 'MultiLineString':
      drawMultiPolyline(name, geojson, geojson.coordinates, options)
      break
    case 'MultiPolygon':
      //drawMulitPolygon(name, geojson, geojson.coordinates, options)
      drawMulitPolygon(name, geojson, geojson.coordinates, options)
      break
    case 'Polygon':
      drawPolygon(name, geojson, geojson.coordinates, options)
      //drawMultiPolyline(name, geojson, geojson.coordinates, options)
      break
    default:
  }
}


export const STYLE = {
  DRAW_POLYGON: {
    color: Cesium.Color.fromCssColorString('#FF0000'),
    outline: true,
    width: 3,
    outlineColor: Cesium.Color.fromCssColorString('#FF0000'),
    outlineWidth: 3,
    fill: false,
  },
  DRAW_POLYGON1: {
    color: Cesium.Color.fromCssColorString('#FF0000'),
    material: new Cesium.ColorMaterialProperty({ color: Cesium.Color.fromCssColorString('#F00'), alpha: 0.7 }),
    outline: true,
    width: 3,
    outlineColor: Cesium.Color.fromCssColorString('#FF0000'),
    outlineWidth: 3,
    fill: true,
  },
  DRAW_POLYGONHighLight: {
    color: Cesium.Color.fromCssColorString('#00ffff'),
    material: new Cesium.ColorMaterialProperty({ color: Cesium.Color.fromCssColorString('#00ffff'), alpha: 1 }),
    outline: true,
    width: 3,
    outlineColor: Cesium.Color.fromCssColorString('#00ffff'),
    outlineWidth: 3,
    fill: false,
  }
}





